﻿/*******************************************************************************
 * AAEngine
 * Copyright (c) 2010 Mike Jarosch
 *
 * Original source PushButton Engine:
 * Copyright (C) 2009 PushButton Labs, LLC
 * For more information see http://www.pushbuttonengine.com
 *
 * This file is licensed under the terms of the MIT license, which is included
 * in the "MIT License.txt" file at the root directory of this SDK.
 ******************************************************************************/

using System.Xml.Linq;
using AAEngine.Engine.Core;
using AAEngine.Engine.Debug;
using AAEngine.Engine.Serialization;

namespace AAEngine.Engine.Entities
{
    /// <summary>
    /// A property reference stores the information necessary to lookup a property
    /// on an entity.
    /// </summary>
    /// <remarks>
    /// These are used to facilitate retrieving information from entities without
    /// requiring a specific interface to be implemented. For example, a component that
    /// handles display information would need to retrieve spatial information from a
    /// spatial component. The spatial component can store its information however it
    /// sees fit. The display component would have a PropertyReference member that would
    /// be initialized to the path of the desired property on the spatial component.
    ///
    /// Property References follow one of three formats, component lookup, global
    /// entity lookup, or xml lookup.  For component lookup the property reference
    /// should start with an @, for global entity lookup the property reference should
    /// start with a #, and for xml lookup the property reference should start with a !.
    /// Following this starting symbol comes the name of the component, entity or XML
    /// Template respectively.
    /// </remarks>
    public class PropertyReference : ISerializable
    {
        private string _property = null;
        private string[] _cachedLookup;

        public string Property
        {
            get { return _property; }
            set
            {
                if (_property != value)
                {
                    _cachedLookup = null;
                }
                _property = value;
            }
        }

        public string[] CachedLookup
        {
            get { return _cachedLookup; }
            set { _cachedLookup = value; }
        }

        public PropertyReference()
            : this(null)
        {

        }

#if WINDOWS_PHONE || XBOX
        public PropertyReference(string property)
#else
        public PropertyReference(string property = null)
#endif
        {
            _property = property;
        }

        public void Serialize(XElement node)
        {
            node.AddElement("#text").Value = _property;
        }

        public object Deserialize(XElement node)
        {
            if (_property != null && _property != node.Value)
            {
                Logger.Warn(this, "Deserialize", "Overwriting property; was '" + _property + "', new value is '" + node.Value + "'");
            }
            _property = node.Value;
            return this;
        }

        public override string ToString()
        {
            return _property;
        }
    }
}
